import { StoryboardScene } from '../../../types/document'
import { ViewportState, SceneBlockData, TimelineStatistics } from './types'

/**
 * 时间线布局计算器
 * 负责将时间数据转换为Canvas坐标和布局信息
 */
export class TimelineLayoutCalculator {
  private static readonly SCENE_HEIGHT = 40
  private static readonly SCENE_PADDING = 4
  private static readonly TIME_SCALE_HEIGHT = 20

  /**
   * 时间转像素坐标
   */
  timeToPixel(time: number, viewport: ViewportState): number {
    return (time * viewport.scale) - viewport.offsetX
  }

  /**
   * 像素坐标转时间
   */
  pixelToTime(pixel: number, viewport: ViewportState): number {
    return (pixel + viewport.offsetX) / viewport.scale
  }

  /**
   * 计算场景块布局数据
   */
  calculateSceneBlocks(scenes: StoryboardScene[], viewport: ViewportState): SceneBlockData[] {
    const blocks: SceneBlockData[] = []
    let currentTime = 0

    for (const scene of scenes) {
      const duration = scene.timing?.duration || scene.duration || 5
      const startX = this.timeToPixel(currentTime, viewport)
      const width = duration * viewport.scale
      
      // 只计算可见区域内的场景块
      if (startX + width >= 0 && startX <= viewport.width) {
        blocks.push({
          scene,
          x: startX,
          width,
          height: TimelineLayoutCalculator.SCENE_HEIGHT,
          y: TimelineLayoutCalculator.TIME_SCALE_HEIGHT + TimelineLayoutCalculator.SCENE_PADDING,
          startTime: currentTime,
          duration
        })
      }

      currentTime += duration
    }

    return blocks
  }

  /**
   * 计算时间刻度标记
   */
  calculateTimeMarks(viewport: ViewportState): Array<{x: number; time: number; label: string; isPrimary: boolean}> {
    const marks: Array<{x: number; time: number; label: string; isPrimary: boolean}> = []
    
    // 根据缩放级别确定刻度间隔
    const scaleLevel = viewport.scale
    let interval: number
    let labelFormat: (time: number) => string

    if (scaleLevel >= 50) {
      interval = 1     // 1秒间隔
      labelFormat = (time) => `${time}s`
    } else if (scaleLevel >= 20) {
      interval = 5     // 5秒间隔
      labelFormat = (time) => `${time}s`
    } else if (scaleLevel >= 5) {
      interval = 10    // 10秒间隔
      labelFormat = (time) => `${time}s`
    } else {
      interval = 30    // 30秒间隔
      labelFormat = (time) => `${Math.floor(time / 60)}:${(time % 60).toString().padStart(2, '0')}`
    }

    // 计算起始时间点
    const startTime = Math.floor(this.pixelToTime(0, viewport) / interval) * interval
    const endTime = this.pixelToTime(viewport.width, viewport)

    for (let time = startTime; time <= endTime; time += interval) {
      const x = this.timeToPixel(time, viewport)
      
      if (x >= 0 && x <= viewport.width) {
        marks.push({
          x,
          time,
          label: labelFormat(time),
          isPrimary: time % (interval * 2) === 0
        })
      }
    }

    return marks
  }

  /**
   * 计算统计信息
   */
  calculateStatistics(scenes: StoryboardScene[]): TimelineStatistics {
    if (scenes.length === 0) {
      return {
        totalDuration: 0,
        sceneCount: 0,
        averageDuration: 0,
        longestScene: null,
        shortestScene: null
      }
    }

    const durations = scenes.map(scene => scene.timing?.duration || scene.duration || 5)
    const totalDuration = durations.reduce((sum, duration) => sum + duration, 0)
    const averageDuration = totalDuration / scenes.length

    let longestScene = { title: scenes[0].title, duration: durations[0] }
    let shortestScene = { title: scenes[0].title, duration: durations[0] }

    scenes.forEach((scene, index) => {
      const duration = durations[index]
      if (duration > longestScene.duration) {
        longestScene = { title: scene.title, duration }
      }
      if (duration < shortestScene.duration) {
        shortestScene = { title: scene.title, duration }
      }
    })

    return {
      totalDuration,
      sceneCount: scenes.length,
      averageDuration,
      longestScene,
      shortestScene
    }
  }

  /**
   * 获取场景在指定位置的插入索引
   */
  getInsertIndex(scenes: StoryboardScene[], targetTime: number): number {
    let currentTime = 0
    
    for (let i = 0; i < scenes.length; i++) {
      const duration = scenes[i].timing?.duration || scenes[i].duration || 5
      
      if (targetTime <= currentTime + duration / 2) {
        return i
      }
      
      currentTime += duration
    }
    
    return scenes.length
  }

  /**
   * 点击测试 - 检查坐标点是否在场景块内
   */
  hitTest(x: number, y: number, sceneBlocks: SceneBlockData[]): SceneBlockData | null {
    for (const block of sceneBlocks) {
      if (x >= block.x && 
          x <= block.x + block.width && 
          y >= block.y && 
          y <= block.y + block.height) {
        return block
      }
    }
    return null
  }
}